module dogre.internals.event;

import dogre.framelistener;
import dogre.log;
import std.conv;

//Generate functions that are called by the C++ (static) frame listener wrapper
string GenStaticListenerHandler(string htype)
{
    return  `extern(C) bool callStaticFrame`~htype~`edHandle(void* ptrToWrapper, ref const(FrameEvent) evt)
             {
                 bool ret = true;
                 foreach(dg; Event.frame`~htype~`ed)
                     ret = dg(evt);
                 return ret;
             }`;
}

mixin(GenStaticListenerHandler("Start"));
mixin(GenStaticListenerHandler("End"));
mixin(GenStaticListenerHandler("RenderingQueu"));


//Function called by C++ (static) loglistener wrapper
extern(C) void callStaticLogListenerHandle(void* ptrToWrapper, const(char)* message, LogMessageLevel lml, bool maskDebug, const(char)* logName)
{
    foreach(dg; Event.messageLogged)
        dg(to!string(message), lml, maskDebug, to!string(logName));
}

abstract class Event
{
    
    static void* ptrToStaticFrameListenerWrapper;
    static void* ptrToStaticLogListenerWrapper;
    
    //Arrays of event handlers
    static bool delegate(ref const(FrameEvent))[] frameStarted;
    static bool delegate(ref const(FrameEvent))[] frameEnded;
    static bool delegate(ref const(FrameEvent))[] frameRenderingQueued;
    static void delegate(string, LogMessageLevel, bool, string)[] messageLogged;
    
    final static this()
    {
        ptrToStaticFrameListenerWrapper = getFrameListenerWrapper(&callStaticFrameStartedHandle,
                                                     &callStaticFrameEndedHandle,
                                                     &callStaticFrameRenderingQueuedHandle);
    
        ptrToStaticLogListenerWrapper = getLogListenerWrapper(&callStaticLogListenerHandle);
    }
}